#include <stdio.h>
#include <string.h>

void transpose(char buff[32], short smps_short[16])
{
	int x, y;
	int smps[16];

	for (x = 0; x < 8; x++) {
		smps[x] = 0;
		
		for (y = 0; y < 16; y++)
			smps[x] |= ((buff[y * 2] & (1 << (7 - x))) >> (7 - x)) << (15 - y);
	}
	
	for (x = 0; x < 8; x++) {
		smps[x + 8] = 0;
		
		for (y = 0; y < 16; y++)
			smps[x + 8] |= ((buff[y * 2 + 1] & (1 << (7 - x))) >> (7 - x)) << (15 - y);
	}

	for (x = 0; x < 16; x++)
		smps_short[x] = (short) (smps[x] - 0x8000);
}

int main(int argc, char const *argv[])
{
	int i;
	FILE *stream[8];

	if (argc != 2) {
		fprintf(stderr, "%s: usage: %s filename_base\n", argv[0], argv[0]);
		return 1;
	}

	for (i = 0; i < 8; i++) {
		char filename[32];
		//if (i != 7)
			sprintf(filename, "%s_%d.raw", argv[1], i);
		//	strcpy(filename, "/dev/null");
		//else
		//	strcpy(filename, "/dev/stdout");
		stream[i] = fopen(filename, "w");

		if (!stream[i]) {
			perror("fopen");
			return 0;
		}
	}

	const unsigned int buff_len = 2048;

	char buff[2048];
	int pos = 0;

	short smps_store[256][2048];
	int smps_done = 0;

	int x = 0;
	int buff_end = 0;

	char synced = 0;

	while (1) {
		if (pos) {
			memcpy(buff, buff + pos, buff_end - pos);
			buff_end -= pos;
			pos = 0;
		}

		int ret;
		if ((ret = fread(buff + buff_end, 1, buff_len - buff_end, stdin)) == 0)
			break;

		buff_end += ret;

		while (pos < buff_end - 32) {
			if (buff[pos] & 0x80) {
				short samples[16];

				transpose(buff + pos, samples);

				for (i = 0; i < 8; i++) {
					smps_store[i][smps_done] = samples[i];
					smps_store[i][smps_done + 1] = samples[i + 8];
				}

				smps_done += 2;
				pos += 32;
				synced = 1;
			} else {
				if (synced)
					fprintf(stderr, "%s: out of sync\n", argv[0]);

				pos++;
				synced = 0;
			}
		}

		for (i = 0; i < 8; i++) {
			if (fwrite(&(smps_store[i][0]), sizeof(short), smps_done, stream[i]) != smps_done)
				perror("fwrite");
		}

		smps_done = 0;
	}

	for (i = 0; i < 8; i++)
		fclose(stream[i]);

	return 0;
}
